#!/usr/sbin/rsct/perl5/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 1999,2002 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# "@(#)92   1.21   src/rsct/registry/cli/bin/mksrdir.perl, srcli, rsct_rpyxh, rpyxht1f3 2/22/01 16:25:24"
######################################################################
#                                                                    #
# Module: mksrdir                                                    #
#                                                                    #
# Purpose:                                                           #
#   mksrdir - Creates (makes) one or more new directories in the     #
#   System Registry.                                                 #
#                                                                    #
# Syntax:                                                            #
#   mksrdir [-h] [-m Mode] [-p] [-s t|p] [-TV] Directory...          #
#                                                                    #
# Flags:                                                             #
#   -h    help - writes this command's usage statement to stdout     #
#   -m    Mode - TODO - to be defined. (security related)            #
#   -p    Creates missing intermediate path name directories.  If    #
#         the -p flag is not specified, the parent directory of      #
#         each directory that we wish to create must already exist.  #
#   -s t |p                                                          #
#         By default if the -s flag is not specified a persistent    #
#         directory will be created in the System Registry. Use the  #
#         -s t flag if instead of a persistent directory you         #
#         want a transient directory created in the System Registry. #
#   -T    Trace. Prints trace messages to stderr.                    #
#   -V    Verbose. Prints verbose messages to stderr.                #
#                                                                    #
# Operands:                                                          #
#   Directory     The name of the directory that we want to create   #
#                 in the system registry. More than one directory    #
#                 operand can be specified.  A relative or absolute  #
#                 directory can be specified.                        #
#                                                                    #
# Description:                                                       #
#   The mksrdir command creates one or more new directories          #
#   specified by the Directory operand. If more than one directory   #
#   operand is specified it is equivalent to the command being       #
#   invoked once for each directory. The directory inherits the      #
#   permission lists from its parent. To use this command you must   #
#   have write permission on the parent directory. By default, all   #
#   directories created will be persistent. If you prefer that a     #
#   transient directory be generated in the System Registry use the  #
#   -s transient flag. A persistent directory may not be created     #
#   under a transient directory. Use the findsr command to determine #
#   if a directory is persistent or transient.                       #
#                                                                    #
# Exit Values:                                                       #
#   0  SR_CLI_SUCCESS        Command completed successfully.         #
#   1  SR_CLI_REGISTRY_ERROR Command terminated due to an underlying #
#                            System Registry error.                  #
#   2  SR_CLI_ERROR          Command terminated due to an underlying #
#                            error in the command script.            #
#   3  SR_CLI_BAD_OPERAND    Command terminated due to user          #
#                            specifying a bad operand.               #
#   4  SR_CLI_BAD_FLAG       Command terminated due to user          #
#                            specifying an invalid flag.             #
#   5  SR_CLI_USER_ERROR     Command terminated due to a user error. #
#                            For example specifying an existing      #
#                            directory to be created.                #
#                                                                    #
# Examples:                                                          #
#   mksrdir -p /samples/Node                                         #
#   mksrdir /samples/Cluster /samples/Node                           #
#                                                                    #
#--------------------------------------------------------------------#
# Inputs:                                                            #
#   /usr/sbin/rsct/msgmaps/srcli.mksrdir.map                         #
#                                                                    #
# Outputs:                                                           #
#   stderr - any error message.                                      #
#                                                                    #
# External Ref:                                                      #
#   Commands: $LSMSG                                                 #
#   Extensions:  CT::SR.pm CT::SRrc.pm                               #
#   Modules:     SR_cli_utils.pm  SR_cli_rc.pm                       #
#   Perl library routines: Getopt::Std                               #
#                                                                    #
# Tab Settings:                                                      #
#   4 and tabs should be expanded to spaces before saving this file. #
#   in vi:  (:set ts=4  and   :%!expand -4)                          #
#                                                                    #
# Change Activity:                                                   #
#   000929 SAB 38317: Initial delivery.                              #
#                                                                    #
######################################################################

#--------------------------------------------------------------------#
# General Program Flow/Logic:                                        #
#                                                                    #
# A. Parse command line flags and operands.                          #
# B. Initialize a session with the System Registry.                  #
# C. Loop through the list of directories (operands),                #
#    create each directory.                                          #
# D. Terminate the Session with the system registry and any other    #
#    necessary cleanup.                                              #
#--------------------------------------------------------------------#

#--------------------------------------------------------------------#
# Included Libraries and Extensions                                  #
#--------------------------------------------------------------------#
use lib "/usr/sbin/rsct/pm";
use locale;
use Getopt::Std; 

use CT_cli_utils qw(printIMsg
                    printEMsg
);

use CT::SRrc;
use CT::SR;
use CT::SR qw(:sr_storage_t);
use SR_cli_utils qw(init_session 
                    term_session 
                    isRelative 
                    printCEMsg
                    $DEFAULT_GLOBAL_MOUNT_POINT
                    error_exit
); 
use SR_cli_rc qw(SR_CLI_REGISTRY_ERROR SR_CLI_BAD_FLAG 
                 SR_CLI_BAD_OPERAND    SR_CLI_USER_ERROR);


#--------------------------------------------------------------------#
# Global Variables                                                   #
#--------------------------------------------------------------------#
# Constants
$TRUE           = 1;
$FALSE          = 0;

# Global variable & defaults
$Opt_Path       = $FALSE;           # Only create dir not entire path
$Opt_Storage_Persistent = $TRUE;    # Only create persistent dirs
$Verbose        = $FALSE;           # Verbose off
$Trace          = $FALSE;           # Trace off

# Messaging variables
$PROGNAME       = "mksrdir";        # Program Name for messages
$MSGCAT         = "srcli.cat";      # Message catalogue for this cmd
$CTDIR          = "/usr/sbin/rsct"; # Cluster directory path
$CTBINDIR       = "$CTDIR/bin";     # Cluster Bin directory path
$LSMSG          = "$CTBINDIR/ctdspmsg"; # Display message routine
$ENV{'MSGMAPPATH'} = "$CTDIR/msgmaps"; # Msg map path for $LSMSG  

%Cleanup = ();                      # Hash of items to cleanup
                                    # {Session} $session to term

#--------------------------------------------------------------------#
# Variables                                                          #
#--------------------------------------------------------------------#
my @Directory      = ();            # Input list of dirs from cmd line
my $rc             = 0;             # Assume a good return code
my $badrc          = 0;             # Assume a good return code
my $Set_work_dir   = $FALSE;        # Current working directory not set

# For use in making directories
my $Tree_handle    = "";            # Set in initSession 
my $Real_directory = "";
my $Storage_type   = "";

my $Mount_point = $DEFAULT_GLOBAL_MOUNT_POINT; # Mount point      


#--------------------------------------------------------------------#
# Main Code                                                          #
#--------------------------------------------------------------------#
# Parse the command line, exit if there are errors 
($rc, @Directory) = parse_cmd_line();
($rc == 0) || error_exit($rc);

# Determine if any relative directories were given, if so, then
# the current working directory needs to be set.
foreach (@Directory) {
    if (isRelative($_)) {$Set_work_dir = $TRUE;}
    $Set_work_dir && last;
}

# Establish a session
# CT::SR::open_tree, CT::SR::mount_directory, 
# CT::SR::change_current_directory
# Uses Env qw(CT_SR_HOME, CT_SR_NUM_RETRIES, CT_SR_TIMEOUT) if they 
# are set.

($rc, $Tree_handle) = init_session($Set_work_dir);
($rc == 0) || error_exit(SR_CLI_REGISTRY_ERROR);

# Add tree handle to the cleanup hash
$Cleanup{Session} = $Tree_handle;

# Create each directory        
$badrc = 0;
foreach $directory (@Directory) {

    # Translate storage type to sr_storage_t enum 
    if ($Opt_Storage_Persistent) { 
        $Storage_type = SR_PERSISTENT;
        $Verbose &&
             printIMsg("IMsgmksrdirCreatingDir", $directory, 
                        "SR_PERSISTENT");
    }
    else {
        $Storage_type = SR_TRANSIENT;
        $Verbose &&
             printIMsg("IMsgmksrdirCreatingDir", $directory, 
                        "SR_TRANSIENT");
    }

    # If the directory is an absolute directory we must prefix it with
    # the mount point.
    if (isRelative($directory)) { 
        $Real_directory = $directory;   # relative directory.
    }
    else {
        $Real_directory = $Mount_point . $directory;
    } 

    $Trace && 
        print STDERR "Calling CT::SR::create_directory($directory)\n";
    $rc = CT::SR::create_directory($Tree_handle, $Real_directory,
         $Storage_type, $Opt_Path); 
    $Trace && 
        print STDERR "CT::SR::create_directory return code: $rc\n";

    $rc = error_check("sr_create_directory", $rc, $directory);
    
    # Continue attempting to create directories unless severe error
    ($rc == SR_CLI_REGISTRY_ERROR) && last;

    # Save the first bad return code 
    if ($rc != 0 && $badrc == 0) { $badrc = $rc; }
}

($badrc == 0) || error_exit($badrc);

# Cleanup 
$rc = term_session($Tree_handle, $Mount_point);

exit $rc;

#--------------------------------------------------------------------#
# End Main Code                                                      #
#--------------------------------------------------------------------#


#--------------------------------------------------------------------#
# parse_cmd_line - Parse the command line for options and operands.  #
#   Set appropriate global variables as outlined below, make sure we #
#   have a valid combination of arguments / options.                 #
#   TODO: all exit -1 should go away when full support coded.        #
#                                                                    #
# Return:                                                            #
#   $rc   0                  Command line parsed fine, no problem.   #
#         SR_CLI_BAD_FLAG    Command line contained a bad flag.      #
#         SR_CLI_BAD_OPERAND Command line was missing an operand.    #
#   @direcory  Array of directories to be created.                   #
#                                                                    #
# Global Variables Modified:                                         #
#   $Opt_Path                output  Set to true if -p flag was used.#
#   $Opt_Storage_Persistent  output  Set to false if -s transient    #
#   $Verbose       output  Set to true if want verbose mode on.      #
#--------------------------------------------------------------------#
sub parse_cmd_line 
{
my(@original_argv) = @ARGV;
my(@directory, $goodrc, $badrc);
my %opts = ();

# Process the command line...
if (getopts('hps:TV', \%opts)==0) {      # Gather options; if errors
    &print_usage;                        # display proper usage
    return SR_CLI_BAD_FLAG;              # return bad flag 
}

if ($#ARGV < 0 && !defined $opts{h}) {   # If no operands then
    &print_usage;                        # display proper usage 
    return SR_CLI_BAD_OPERAND;           # return bad operand 
}

# Get the arguments...
@directory = @ARGV;                      # user specified directory 

# See which options/flags were used...
if (defined $opts{h}) {                 # -h, help request  
    &print_usage;                       # print usage statement
    exit(0);                            # all done with good return!
}

# TODO: still need to support security
if (defined $opts{m}) {                 # -m mode (security)
    printf("mksrdir -m flag is not yet supported!\n");
    printf("  Waiting on the underlying support in the System Registry.\n");
    &print_usage;
    return SR_CLI_BAD_FLAG;             # return bad flag 
}

if (defined $opts{p}) {                 # -p create parents
    $Opt_Path = $TRUE;
}

if (defined $opts{s}) {                 # -s <storage_type> 
    if ($opts{s} =~ /^t$/) {        
        $Opt_Storage_Persistent = $FALSE;  # create transient directory
    }
    elsif ($opts{s} =~ /^s$/) {
        &printCEMsg(EMsgSRcliImproperUsageFlag, '"-s $opts{s}"');
        &print_usage;
        return SR_CLI_BAD_FLAG;
    }
}

# reserve -T for future tracing
if (defined $opts{T}) {                # -T trace   
    $Trace= $TRUE;
}

if (defined $opts{V}) {                # -V verbose 
    $Verbose = $TRUE;
}

return(0, @directory);                  # Good return.
}   # end parse_cmd_line


#--------------------------------------------------------------------#
# error_check:                                                       #
#   Checks the return code from the SR function.  If an error is     #
#   detected appropriate error messages will be displayed and        #
#   SR CLI return code set.                                          #
#                                                                    #
# Parameters:                                                        #
#   $sr_function  - Name of the SR function that was called and      #
#                   whose error code we are checking.                #
#   $sr_rc        - SR function return code.                         #
#   $directory    - Name of the directory trying to create.          #
#                                                                    #
# Return values:                                                     #
#   None.                                                            #
#                                                                    #
# Global References:                                                 #
#   None.                                                            #
#--------------------------------------------------------------------#
sub error_check
{
my ($sr_function, $sr_rc, $table_name) = @_;
my $rc = 0;

if ($sr_rc != 0) {
    if ($sr_rc == SR_NO_PERMISSION) {
        printEMsg("EMsgmksrdirPermissionError", $directory);
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_DIRECTORY_EXISTS) {
        printEMsg("EMsgmksrdirDirAlreadyExists", $directory);
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_NO_DIRECTORY) {
        printEMsg("EMsgmksrdirBadDirPath", $directory);
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc ==SR_PERSISTENT_UNDER_TRANSIENT) {
        printEMsg("EMsgmksrdirTransientParent", $directory);
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc ==SR_INVALID_DIRECTORY) {
        printEMsg("EMsgmksrdirInvalidDir", $directory);
        $rc = SR_CLI_USER_ERROR;
    }
    else {
        # If there is a real System Registry error, just quit
        printEMsg("EMsgmksrdirCreateDirError", $directory);
        printCEMsg("EMsgSRcliSRCommandFailure", $sr_function, $sr_rc);
        $rc = SR_CLI_REGISTRY_ERROR;
    }
}

return ($rc);
}   # end error_check


#--------------------------------------------------------------------#
# print_usage : print the usage statement (syntax) to stdout.        #
#   See this command's prologue syntax section for current usage.    #
#--------------------------------------------------------------------#
sub print_usage
{
&printIMsg("IMsgmksrdirUsage");
}   # end print_usage


#--------------------------------------------------------------------#
# End File                                                           #
#--------------------------------------------------------------------#
